package mips.instructions;

/**
 * <code>TGEI</code> instruction<br/>
 * Trap If Greater Than Or Equal Immediate<br/>
 * @author jnmartin84@gmail.com
 */
public class TGEI extends Instruction {

	private static final String INSTRUCTION_NAME = "TGEI";
	private static final TGEI INSTANCE = new TGEI();

	private TGEI(){}

	public static final TGEI getInstance() {
		return INSTANCE;
	}

	/**
	 * <b>Format:</b><br/>
	 * TGEI rs, immediate<br/><br/>
	 * <b>Description:</b><br/>
	 * The 16-bit immediate is sign-extended and compared to the contents of<br/>
	 * general register rs. Considering both quantities as signed integers, if the<br/>
	 * contents of general register rs are greater than or equal to the sign-<br/>
	 * extended immediate, a trap exception occurs.<br/><br/>
	 * <b>Operation:</b><br/>
	 * T: if GPR[rs] &ge; (immediate<sub>15</sub>)<sup>16</sup> || immediate<sub>15...0</sub> then<br/>
	 * TrapException<br/>
	 * endif<br/>
	 * @throws mips.exceptions.TrapException
	 */
	@Override
	public final void execute(final int instruction) throws mips.exceptions.TrapException {

		mips.instructions.Instruction.RS = (instruction >> 21) & 0x0000001F;
		mips.instructions.Instruction.IMMED = mips.instructions.Instruction.signExtendH(instruction & 0x0000FFFF);

		if(mips.R4300i.GPR[mips.instructions.Instruction.RS] >= mips.instructions.Instruction.IMMED) {
			throw new mips.exceptions.TrapException(mips.R4300i.PC,instruction);
		}

		mips.R4300i.PC = mips.R4300i.nPC;
		mips.R4300i.nPC = mips.R4300i.PC + 4;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String emit(final int instruction) {

		mips.instructions.Instruction.RS = (instruction >> 21) & 0x0000001F;
		mips.instructions.Instruction.IMMED = mips.instructions.Instruction.signExtendH(instruction & 0x0000FFFF);
		
		return	"		if(mips.CPU.GPR["+mips.instructions.Instruction.RS+"] >= "+mips.instructions.Instruction.IMMED+") {\n" + 
				"			throw new mips.exceptions.TrapException(mips.CPU.PC,"+String.format("0x%08X",instruction)+");\n" + 
				"		}\n" + 
				"		\n" + 
				"		mips.CPU.PC = mips.CPU.nPC;\n" + 
				"		mips.CPU.nPC = mips.CPU.PC + 4;\n";
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName(final int instruction) {
		return getName();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName() {
		return INSTRUCTION_NAME;
	}
}